<script lang="ts" setup>
/**
 * Expose
 * @init 初始化组件方法
 *
 * Emits
 * @code 组件已输入内容
 *
 * Props
 * @length 验证码位数 --int
 *
 * @gap 位间距
 *
 * @height 占位高
 *
 * @size 容字体大小
 */
import { computed, nextTick, ref, watch, defineExpose } from 'vue'
import { hasUnit } from '@U/common'

defineProps({
  length: {
    type: String,
    required: false,
    default: '6',
  },
  gap: {
    type: String,
    required: false,
    default: '22',
  },
  height: {
    type: String,
    required: false,
    default: '85',
  },
  size: {
    type: String,
    required: false,
    default: '70',
  },
})

const init = () => {
  inputVal.value = ''
}
defineExpose({ init })

const emits = defineEmits(['code'])

// input 值
const inputVal = ref('')
watch(
  () => inputVal.value,
  (newVal) => {
    if (newVal.length === 6) {
      emits('code', newVal)
    }
  },
)

// 唤起键盘
const focusState = ref(true)
const fakeInputBlur = () => {
  focusState.value = false
}
const canKeyBoard = async () => {
  await nextTick(() => {
    focusState.value = true
  })
}

// 显示列表
const codeList = computed(() => inputVal.value.split(''))
// 是否聚焦
const canKeyFocus = computed(() => codeList.value.length + 1)
// 是否有值
const canKeyAct = computed(() => canKeyFocus.value - 1)

</script>

<template>
  <div
    :style="{ height: hasUnit(height) }"
    class="prm-key-board"
    @tap="canKeyBoard"
  >
    <input
      v-model="inputVal"
      :focus="focusState"
      class="fake-input"
      maxlength="6"
      type="number"
      @blur="fakeInputBlur"
    >
    <div
      v-for="d in +length"
      :key="d"
      :class="{ 'key-box': true, 'key-focus': canKeyFocus === d, 'key-act': canKeyAct >= d }"
      :style="{
        height: hasUnit(height),
        lineHeight: hasUnit(height),
        fontSize: hasUnit(size),
        marginRight: `${ d === length ? '0' : gap }rpx`
      }"
    >
      {{ codeList[d - 1] }}
    </div>
  </div>
</template>

<style lang="less" scoped>
.prm-key-board {
  position: relative;
  width: 100%;
  background: transparent;
  display: flex;
  justify-content: space-between;
  .fake-input {
    position: fixed;
    top: -1000rpx;
    left: -1000rpx;
    z-index: -999;
    caret-color: transparent;
    color: transparent;
    opacity: 0;
  }
  .key-box {
    text-align: center;
    flex: 1 1;
    border-bottom: solid 2rpx #d9d9d9;
    color: #000000;
    opacity: 0.65;
    color: rgba(0, 0, 0, 0);
    transition: all 0.3s;
  }
  .key-focus {
    border-color: rgba(0, 0, 0, 0.85);
    position: relative;
  }
  .key-focus::after {
    position: absolute;
    top: 10rpx;
    left: 0;
    right: 0;
    content: "";
    margin: auto;
    width: 4rpx;
    height: 60rpx;
    background: #1890FF;
    opacity: 0.2;
    animation: 1s breath infinite;
  }
  @keyframes breath {
    0% { opacity: 0.2 }
    50% { opacity: 1 }
    100% { opacity: 0.2 }
  }
  .key-act {
    border-color: #1890FF;
    color: rgba(0, 0, 0, 85);
  }
}
</style>
